package com.wxzz.elearing.course.amqp.producer;

import com.alibaba.fastjson.JSONObject;
import com.wxzz.elearning.common.bean.RabbitMQConfiguration;
import com.wxzz.elearning.common.constants.RabbitPool;
import com.wxzz.elearning.common.constants.RedisConstants;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.UUID;

@Component
@Slf4j
public class CourseProducer {


    @Autowired
    private RabbitTemplate rabbitTemplate;

    public void ackMQSender(String msg) {
        log.info("send ack message :" + msg);
        //消息消费者确认收到消息后，手动ack回执
        // 生产者发送消息到exchange后没有绑定的queue时将消息退回
        rabbitTemplate.setReturnCallback((message, replyCode, replyText, exchange, routingKey) -> {
            log.error("ackMQSender 发送消息被退回" + exchange + routingKey);
        });
        //消息消费者确认收到消息后，手动ack回执
        // 生产者发送消息confirm检测
        this.rabbitTemplate.setConfirmCallback((correlationData, ack, cause) -> {
            if (!ack) {
                log.error("ackMQSender 消息发送失败" + cause + correlationData.toString());
            } else {
                log.info("ackMQSender 消息发送成功 ");
            }
        });
        //发送 这里不设置routing_key,因为设置了也无效，发送端的routing_key写任何字符都会被忽略。
        this.rabbitTemplate.convertAndSend(RabbitPool.ACK_FANOUT_EXCHANGE, "", msg);
    }


    /**
     * 课程同步
     *
     * @param msg
     */
    public void sendCourseUpdate(String msg) {
        log.info("sendCourseUpdate message :" + msg);
        //消息消费者确认收到消息后，手动ack回执
        // 生产者发送消息到exchange后没有绑定的queue时将消息退回
        rabbitTemplate.setReturnCallback((message, replyCode, replyText, exchange, routingKey) -> {
            log.error("sendCourseUpdate 发送消息被退回" + exchange + routingKey);
        });
        //消息消费者确认收到消息后，手动ack回执
        // 生产者发送消息confirm检测
        this.rabbitTemplate.setConfirmCallback((correlationData, ack, cause) -> {
            if (!ack) {
                log.error("sendCourseUpdate 消息发送失败" + cause + correlationData.toString());
            } else {
                log.info("sendCourseUpdate 消息发送成功 ");
            }
        });
        //发送 这里不设置routing_key,因为设置了也无效，发送端的routing_key写任何字符都会被忽略。
        this.rabbitTemplate.convertAndSend(RabbitPool.COURSE_UPDATE_QUEUE, msg);
    }

    /**
     * 修改培训
     */
    public void trainSurveyUpdateStatus(Long trainSurveyId, LocalDateTime startTime) {
        //学习计划到期提醒
        String uuid = UUID.randomUUID().toString() + RabbitMQConfiguration.QUEUE_TYPE10;
        JSONObject res = new JSONObject();
        res.put("uuid", uuid);
        res.put("id", trainSurveyId);
        res.put("type", RabbitMQConfiguration.QUEUE_TYPE10);
        res.put("status", 1);
        //提前发送消息
        rabbitTemplate.convertAndSend(
                RabbitMQConfiguration.WXZZ_DELAY_EXCHANGE,
                RabbitMQConfiguration.WXZZ_COURSE_DELAY_KEY,
                res.toJSONString(),
                (msg) -> {
                    Long now = LocalDateTime.now().toInstant(ZoneOffset.of("+8")).toEpochMilli();
                    Long start = startTime.toInstant(ZoneOffset.of("+8")).toEpochMilli();
                    log.info("当前需插入的队列任务时差:{}", (start - now) / 1000);
                    msg.getMessageProperties().setDelay((int) (start - now));
                    return msg;
                });
        //保持消息的唯一
        redisTemplate.opsForValue().set(RedisConstants.DEAL_QUEUE_LIVETELECAST + trainSurveyId + RabbitMQConfiguration.QUEUE_TYPE10 + 1, uuid);
    }


    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    /**
     * 学习计划到期提醒
     *
     * @param platformLivetelecastId
     * @param startTime              开始提醒时间
     */
    public void remindStudyPlan(Long platformLivetelecastId, LocalDateTime startTime) {
        //学习计划到期提醒
        String uuid = UUID.randomUUID().toString() + RabbitMQConfiguration.QUEUE_TYPE5;
        JSONObject res = new JSONObject();
        res.put("uuid", uuid);
        res.put("id", platformLivetelecastId);
        res.put("type", RabbitMQConfiguration.QUEUE_TYPE5);
        res.put("status", 0);
        //提前发送消息
        rabbitTemplate.convertAndSend(
                RabbitMQConfiguration.WXZZ_DELAY_EXCHANGE,
                RabbitMQConfiguration.WXZZ_COURSE_DELAY_KEY,
                res.toJSONString(),
                (msg) -> {
                    Long now = LocalDateTime.now().toInstant(ZoneOffset.of("+8")).toEpochMilli();
                    Long start = startTime.toInstant(ZoneOffset.of("+8")).toEpochMilli();
                    log.info("当前需插入的队列任务时差:{}", (start - now) / 1000);
                    msg.getMessageProperties().setDelay((int) (start - now));
                    return msg;
                });
        //保持消息的唯一
        redisTemplate.opsForValue().set(RedisConstants.DEAL_QUEUE_LIVETELECAST + platformLivetelecastId + RabbitMQConfiguration.QUEUE_TYPE5 + 0, uuid);
        //学习计划即将到期提醒
        String willUuid = UUID.randomUUID().toString() + RabbitMQConfiguration.QUEUE_TYPE4;
        JSONObject willRes = new JSONObject();
        willRes.put("uuid", willUuid);
        willRes.put("id", platformLivetelecastId);
        willRes.put("type", RabbitMQConfiguration.QUEUE_TYPE4);
        willRes.put("status", 0);
        //提前发送消息
        rabbitTemplate.convertAndSend(
                RabbitMQConfiguration.WXZZ_DELAY_EXCHANGE,
                RabbitMQConfiguration.WXZZ_COURSE_DELAY_KEY,
                willRes.toJSONString(),
                (msg) -> {
                    Long now = LocalDateTime.now().toInstant(ZoneOffset.of("+8")).toEpochMilli();
                    Long start = startTime.toInstant(ZoneOffset.of("+8")).toEpochMilli();
                    log.info("当前需插入的队列任务时差:{}", (start - now) / 1000);
                    if ((start - now - 1000 * 60 * 5) < 0) {
                        msg.getMessageProperties().setDelay(0);
                    } else {
                        msg.getMessageProperties().setDelay((int) (start - now - 1000 * 60 * 5));
                    }
                    return msg;
                });
        //保持消息的唯一
        redisTemplate.opsForValue().set(RedisConstants.DEAL_QUEUE_LIVETELECAST + platformLivetelecastId + RabbitMQConfiguration.QUEUE_TYPE4 + 0, willUuid);
    }


}
